﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DynORM.Interfaces;
using DynORM.Mappers;
using DynORM.Enums;
using DynORM;
using DynORM.ValueObjects;
using DynORM.ReferenceObjects;
using System.Xml.Serialization;
using System.Xml;
using System.IO;

namespace UnitTests.DAL
{
    [TestClass]
    public class PostgreSQLDatabaseUnitTests
    {
        static string dbName = "TestDB";
        static string pooling = "Pooling=false;";//otherwise it won't let drop db (db will be in use with connections in pool)
        string connectionStringToServer = "Server=127.0.0.1;Port=5432;User Id=postgres;Password=postgres;"+pooling;
        string connectionStringToDataBase = "Server=127.0.0.1;Port=5432;User Id=postgres;Password=postgres;Database="+dbName+";"+pooling;

        private IRowDescriptor GenerateNewRowDescriptor(string tableName)
        {
            Dictionary<int, IFieldDescriptor> pkFieldDescs = new Dictionary<int, IFieldDescriptor>();
            pkFieldDescs.Add(0, new FieldDescriptor(typeof(Guid), "RowID"));
            PrimaryKeyDescriptor pkd = new PrimaryKeyDescriptor(tableName, pkFieldDescs, tableName + "_PK");
            List<FieldDescriptor> fieldDescs = new List<FieldDescriptor>();
            fieldDescs.Add(new FieldDescriptor(typeof(string), "TestColumn"));
            RowDescriptor rd = new RowDescriptor(tableName, fieldDescs, new List<IRelationDescriptor>() { pkd });
            return rd;
        }

        private IORMDatabase GenerateTestDB(string dbName)
        {
            IORMDatabase result = new Database(dbName);
            IRowDescriptor rd = GenerateNewRowDescriptor("TestTable");
            result.AddTable(rd);
            return result;
        }

        [TestMethod]
        public void CreateNewDatabaseTest()
        {
            IORMDatabase db = GenerateTestDB(dbName);
            DatabaseMapper.CreateDatabase(connectionStringToServer, DBMSTypes.PostgreSQL, db);
            DatabaseMapper.DropDatabase(connectionStringToDataBase, DBMSTypes.PostgreSQL, db.DBName);
        }

        [TestMethod]
        public void CreateNewDatabaseTest2()
        {
            IORMDatabase db = GenerateTestDB(dbName);
            DatabaseMapper.CreateDatabase(connectionStringToServer, DBMSTypes.PostgreSQL, db, true, true);
            DatabaseMapper.DropDatabase(connectionStringToDataBase, DBMSTypes.PostgreSQL, db.DBName);
        }

        [TestMethod]
        public void SerializeDatabaseTest()
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlTextWriter writer = new XmlTextWriter(ms, UTF8Encoding.Default);

                XmlSerializer formatter = new XmlSerializer(typeof(Database));
                IORMDatabase db = GenerateTestDB(dbName);
                formatter.Serialize(writer, db);

                ms.Position = 0;
                StreamReader sr = new StreamReader(ms);
                string xml = sr.ReadToEnd();
            }
            //Assert.AreEqual(xml, @"");
        }

        [TestMethod]
        public void DeserializeDatabaseTest()
        {
            IORMDatabase db;
            using (MemoryStream ms = new MemoryStream())
            {
                XmlTextWriter writer = new XmlTextWriter(ms, UTF8Encoding.Default);

                XmlSerializer formatter = new XmlSerializer(typeof(Database));
                db = GenerateTestDB(dbName);
                formatter.Serialize(writer, db);
                db = null;

                ms.Position = 0;
                XmlTextReader reader = new XmlTextReader(ms);
                db = (IORMDatabase)formatter.Deserialize(reader);
            }
            Assert.IsNotNull(db);

        }

    }
}
